/*----------------------------------------------------------------------------*\
|
|						Public Interface to Muse Technology
|
|							     www.muse.com
| Author : SunJun 
| Email : sundoom@msn.com
\*----------------------------------------------------------------------------*/

//////////////////////////////////////////////////////////////////////////
// $Id: Muse.h,v 1.1 2009/04/03 12:46:09 sunjun Exp $
//////////////////////////////////////////////////////////////////////////

#ifndef __Muse__
#define __Muse__

//////////////////////////////////////////////////////////////////////////

#if defined __cplusplus

//////////////////////////////////////////////////////////////////////////

#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <time.h>
#include <malloc.h>

//////////////////////////////////////////////////////////////////////////

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <mmsystem.h>
#pragma comment(lib,"winmm.lib")

//////////////////////////////////////////////////////////////////////////

#define NAMESPACE_SUPPORT

#ifdef NAMESPACE_SUPPORT
	#define NAMESPACE_NAME	Muse
	#define NAMESPACE_BEGIN	namespace NAMESPACE_NAME {
	#define NAMESPACE_END	}
	#define NAMESPACE_USE	using namespace NAMESPACE_NAME;
#else
	#define NAMESPACE_NAME
	#define NAMESPACE_BEGIN
	#define NAMESPACE_END
	#define NAMESPACE_USE
#endif

//////////////////////////////////////////////////////////////////////////

#ifndef CDECL
	#define CDECL		__cdecl					// standard c function
#endif

#ifndef STDCALL
	#define STDCALL		__stdcall				// standard calling convention
#endif

#ifndef INLINE
	#define INLINE		inline
#endif

#ifndef DLLIMPORT
	#define DLLIMPORT	__declspec(dllimport)	// import function from dll
#endif

#ifndef DLLEXPORT
	#define DLLEXPORT	__declspec(dllexport)	// export function to dll
#endif

#ifndef API
	#ifdef DYNAMIC_LIB
		#define API		DLLEXPORT
		#define CAPI	extern "C" DLLEXPORT
	#elif STATIC_LIB
		#define API
		#define CAPI
	#elif USE_DYNAMIC_LIB
		#define API		DLLIMPORT
		#define CAPI	extern "C" DLLIMPORT
	#elif USE_STATIC_LIB
		#define API
		#define CAPI
	#else		
		#define API		DLLIMPORT
		#define CAPI	extern "C" DLLIMPORT
	#endif
#endif

//////////////////////////////////////////////////////////////////////////

#undef CHAR
#undef VOID
#undef HANDLE

typedef __int64				I64;
typedef signed int			I32;
typedef signed short		I16;
typedef signed char			I8;

typedef unsigned __int64	U64;
typedef unsigned int		U32;
typedef unsigned short		U16;
typedef unsigned char		U8;

typedef float				F32;
typedef double				F64;

typedef char				CHAR;
typedef wchar_t				WCHAR;

typedef void				VOID;
typedef void*				HANDLE;	

#undef NULL
#ifndef NULL
#ifdef __cplusplus
#define NULL    0
#else
#define NULL    ((void *)0)
#endif
#endif

#ifndef FALSE
#define FALSE	0
#endif
#ifndef TRUE
#define TRUE    1
#endif
#undef BOOL
typedef int     BOOL;

//////////////////////////////////////////////////////////////////////////

#define	MAX_I8			0x7f
#define	MIN_I8			0x80
#define	MAX_U8			0xff
#define	MIN_U8			0x00
#define	MAX_I16			0x7fff
#define	MIN_I16			0x8000
#define	MAX_U16			0xffff
#define	MIN_U16			0x0000
#define	MAX_I32			0x7fffffff
#define	MIN_I32			0x80000000
#define	MAX_U32			0xffffffff
#define	MIN_U32			0x00000000
#define	MAX_I64			0x7fffffffffffffff
#define	MIN_I64			0x8000000000000000
#define	MAX_U64			0xffffffffffffffff
#define	MIN_U64			0x0000000000000000
#define	MAX_F32			3.402823466e+38F
#define	MIN_F32			(-3.402823466e+38F)
#define	MAX_F64			1.7976931348623158e+308
#define	MIN_F64			(-1.7976931348623158e+308)
#define EPS_F32			1.192092896e-07F			// smallest number not zero
#define EPS_F64			2.2204460492503131e-016		// smallest number not zero
#define IEEE_1_0		0x3f800000					// integer representation of 1.0
#define IEEE_255_0		0x437f0000					// integer representation of 255.0
#define IEEE_MAX_F32	0x7f7fffff					// integer representation of max F32
#define IEEE_MIN_F32	0xff7fffff					// integer representation of min F32
#define	N_PI			3.14159265358979323846
#define	MIN(a, b)		((a) < (b) ? (a) : (b))		// returns the min value between a and b
#define	MAX(a, b)		((a) > (b) ? (a) : (b))		// returns the max value between a and b

//////////////////////////////////////////////////////////////////////////	

NAMESPACE_BEGIN

//////////////////////////////////////////////////////////////////////////	

	INLINE API const CHAR * CDECL VA( const CHAR *format, ... );
	INLINE API VOID CDECL MAssert( const CHAR * msg );
	INLINE API VOID CDECL MAssert( const CHAR * msg, const CHAR * filename, I32 line );
	INLINE API VOID CDECL MPrint( const CHAR * msg );

	//////////////////////////////////////////////////////////////////////////

	#ifndef DO_GUARD
		#define DO_GUARD 1
	#endif

	#ifndef DO_CHECK
		#define DO_CHECK 1
	#endif

	#if _DEBUG || !DO_GUARD
		#define GUARD(func)	{static const CHAR *__FUNC_NAME__=#func;		
  
		#define UNGUARD		}	
	#else
		#define GUARD(func)	{ static const CHAR *__FUNC_NAME__=#func; try{
		#define UNGUARD		} catch(CHAR*Err){throw Err;}catch(...){ MAssert(__FUNC_NAME__); throw;}}
	#endif
  
	#if DO_CHECK
		#define CHECK(expr)	{if(!(expr))MAssert( #expr, __FILE__, __LINE__ );}
	#else
		#define CHECK(expr)	if(expr){}
	#endif	

	//////////////////////////////////////////////////////////////////////////

	INLINE API VOID * CDECL MMalloc( U32 size, const CHAR * filename = 0, I32 line = 0 );
	INLINE API VOID	CDECL MFree( VOID* p );	

	#define MNEW(x)	new( __FILE__, __LINE__ ) x
	#define MDELETE(x)	delete x
	
//////////////////////////////////////////////////////////////////////////

NAMESPACE_END

//////////////////////////////////////////////////////////////////////////

#ifdef MUSE_MEMORY
	INLINE VOID * CDECL operator new(U32 cb)
	{ return NAMESPACE_NAME::MMalloc( cb, NULL, 0 ); }
	INLINE VOID* CDECL operator new(U32 cb, const CHAR* file, I32 line)
	{ return NAMESPACE_NAME::MMalloc( cb, file, line ); }
	INLINE VOID * CDECL operator new[](U32 cb) 
	{ return NAMESPACE_NAME::MMalloc( cb, NULL, 0 ); }
	INLINE VOID* CDECL operator new[](U32 cb, const CHAR* file, I32 line)
	{ return NAMESPACE_NAME::MMalloc( cb, file, line ); }
	INLINE VOID CDECL operator delete(VOID *p)
	{ NAMESPACE_NAME::MFree(p); }
	INLINE VOID CDECL operator delete[](VOID *p)
	{ NAMESPACE_NAME::MFree(p);}
#endif

//////////////////////////////////////////////////////////////////////////

#include <vector>
#include <map>
#include <string>
typedef std::string	Str;
typedef std::wstring WStr;

//////////////////////////////////////////////////////////////////////////	

NAMESPACE_BEGIN

//////////////////////////////////////////////////////////////////////////

	INLINE API std::vector<Str> CDECL MTokenize( const Str& in, CHAR split = ' ' );

//////////////////////////////////////////////////////////////////////////

NAMESPACE_END

//////////////////////////////////////////////////////////////////////////

#endif // __cplusplus

//////////////////////////////////////////////////////////////////////////

#endif // __Muse__

//////////////////////////////////////////////////////////////////////////
